// 第一题

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");
 
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});
 
const lines = [];
let n, m;
rl.on("line", (line) => {
  lines.push(line);
 
  if (lines.length === 1) {
    [n, m] = lines[0].split(" ").map(Number);
  }
 
  if (n && lines.length === n + 1) {
    lines.shift();
    const matrix = lines.map((line) => line.split(" "));
    console.log(getResult(matrix, n, m));
    lines.length = 0;
  }
});
 
function getResult(matrix, n, m) {
  const checked = new Set();
 
  const offset = [
    [0, -1],
    [0, 1],
    [-1, 0],
    [1, 0],
  ];
 
  function dfs(i, j, count, out) {
    const pos = `${i}-${j}`;
 
    if (
      i < 0 ||
      i >= n ||
      j < 0 ||
      j >= m ||
      matrix[i][j] === "X" ||
      checked.has(pos)
    )
      return count;
 
    checked.add(pos);
 
    if (i === 0 || i === n - 1 || j === 0 || j === m - 1) out.push([i, j]);
 
    count++;
 
    for (let k = 0; k < offset.length; k++) {
      const [offsetX, offsetY] = offset[k];
      const newI = i + offsetX;
      const newJ = j + offsetY;
      count = dfs(newI, newJ, count, out);
    }
 
    return count;
  }
 
  const ans = [];
 
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < m; j++) {
      if (matrix[i][j] === "O" && !checked.has(`${i}-${j}`)) {
        const out = [];
        const count = dfs(i, j, 0, out);
        if (out.length === 1) {
          ans.push([...out[0], count]);
        }
      }
    }
  }
 
  if (!ans.length) return "NULL";
 
  ans.sort((a, b) => b[2] - a[2]);
 
  if (ans.length === 1 || ans[0][2] > ans[1][2]) {
    return ans[0].join(" ");
  } else {
    return ans[0][2];
  }
}



// 第二题

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");
 
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});
 
const lines = [];
rl.on("line", (line) => {
  lines.push(line);
 
  if (lines.length === 2) {
    const arr = lines[0].split(" ");
    const n = parseInt(lines[1]);
 
    console.log(getResult(arr, n));
 
    lines.length = 0;
  }
});
 
function getResult(arr, n) {
  // count用于统计滑动窗口内各种颜色的数目
  const count = {
    0: 0,
    1: 0,
    2: 0,
  };
 
  // 初始滑动窗口的左右边界，注意这里的右边界r是不包含了，为了方便后面进行slice
  let l = 0;
  let r = l + n;
 
  // 统计初始滑动窗口中各种颜色的数量
  arr.slice(l, r).forEach((c) => {
    count[c]++;
  });
 
  // 将初始滑动窗口内部最多颜色数量给max
  let max = Math.max.apply(null, Object.values(count));
 
  // 如果滑动窗口右边界未达到数组尾巴，就继续右移
  // 注意，初始滑窗的右边界r是不包含的，因此r可以直接当成下一个滑窗的右边界使用
  while (r < arr.length) {
    // 当滑动窗口右移后，新的滑动窗口相比移动前来看，新增了arr[r]，失去了arr[l]，注意此时左边界l还是指向上一个滑窗的左边界，而不是新滑窗的左边界，因此可以直接通过arr[l]取得失去的
    const add = arr[r++];
    const remove = arr[l++];
 
    count[add]++;
    count[remove]--;
 
    // 只有新增数量的颜色可能突破最大值
    max = Math.max(max, count[add]);
  }
 
  return max;
}



// 第三题

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");
 
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});
 
const lines = [];
let n;
rl.on("line", (line) => {
  lines.push(line);
 
  if (lines.length === 1) {
    n = lines[0] - 0;
  }
 
  if (n && lines.length === n + 2) {
    lines.shift();
    const [tx, ty] = lines.pop().split(" ").map(Number);
    const nodes = lines.map((line) => line.split(" ").map(Number));
 
    console.log(getResult(nodes, tx, ty));
 
    lines.length = 0;
  }
});
 
/**
 *
 * @param {*} nodes 数组，存储树中所有节点，数组元素node也是数组，node = [val, left, right] ，其中val是node节点的内容值，left是node节点的左子节点的索引，right是node节点的右子节点的索引，索引是相对nodes而言的
 * @param {*} tx 目标位置x坐标
 * @param {*} ty 目标位置y坐标
 */
function getResult(nodes, tx, ty) {
  const matrix = [];
 
  function dfs(node, level) {
    if (!node) return;
 
    // 2023.1.16更新代码逻辑，之前本题只有用例1，因此误以为题目中的树指的是二叉树，因此错误意味一个节点最多只有两个子节点，但是后面补充了更多用例，发现本题的树是多叉树
    // const [val, left, right] = node;
    const val = node[0];
    matrix[level] ? matrix[level].push(val) : (matrix[level] = [val]);
 
    // 2023.1.16更新代码逻辑，之前本题只有用例1，因此误以为题目中的树指的是二叉树，因此错误意味一个节点最多只有两个子节点，但是后面补充了更多用例，发现本题的树是多叉树
    // dfs(nodes[left], level + 1);
    // dfs(nodes[right], level + 1);
    for (let i = 1; i < node.length; i++) {
      dfs(nodes[node[i]], level + 1);
    }
  }
 
  dfs(nodes[0], 0);
 
  if (matrix[tx] && matrix[tx][ty]) {
    return `{${matrix[tx][ty]}}`;
  } else {
    return "{}";
  }
}
